package cn.uncode.springcloud.admin.controller.system;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;

import cn.uncode.springcloud.admin.model.system.dto.GatewayRouteDTO;
import cn.uncode.springcloud.admin.service.system.GatewayRouteService;
import cn.uncode.springcloud.starter.boot.app.AppInfo;
import cn.uncode.springcloud.starter.web.result.P;
import cn.uncode.springcloud.starter.web.result.R;


@Controller
@RequestMapping("/gateway")
public class GatewayRouteController {

    @Autowired 
    private GatewayRouteService gatewayRouteService;
    
    @Autowired
    private EurekaClient eurekaClient;

    
    @RequestMapping("/routes/{version}")
    @ResponseBody
    public R<List<GatewayRouteDTO>> getRouteDefinitionsByVersion(@PathVariable long version){
    	long localVersion = gatewayRouteService.getLastVersion();
    	if(version == 0 || localVersion > version) {
    		Date time = new Date(version);
    		List<GatewayRouteDTO> list = gatewayRouteService.getRoutes(time);
        	return R.success(list, localVersion + "");
    	}else {
    		return R.success(localVersion + "");
    	}
    }
    
    @RequestMapping("/last")
    @ResponseBody
    public R<Long> getLastVersion(){
    	long version = gatewayRouteService.getLastVersion();
    	return R.success(version);
    }
    
    @RequestMapping("/publish")
    @ResponseBody
    public R<Long> publish(){
    	long current = System.currentTimeMillis();
    	gatewayRouteService.publish(current);
    	return R.success(current);
    }

    //添加路由信息
    @RequestMapping(value = "/add" , method = RequestMethod.POST)
    @ResponseBody
    public  R<Boolean> add(@RequestBody GatewayRouteDTO route){
    	long id = gatewayRouteService.add(route);
    	if(id > 0) {
    		return R.success();
    	}
        return R.failure();
    }

    @RequestMapping(value = "/update" , method = RequestMethod.POST)
    @ResponseBody 
    public R<Boolean> edit(@RequestBody GatewayRouteDTO route){
    	int count = gatewayRouteService.update(route);
    	if(count > 0) {
    		return R.success();
    	}
        return R.failure();
    }
    
    @RequestMapping(value = "/updateOrder" , method = RequestMethod.POST)
    @ResponseBody 
    public R<Boolean> updateOrder(@RequestParam long id, @RequestParam int order){
    	GatewayRouteDTO route = new GatewayRouteDTO();
    	route.setId(id);
    	route.setRouteOrder(order);
    	int count = gatewayRouteService.update(route);
    	if(count > 0) {
    		return R.success();
    	}
        return R.failure();
    }


    //打开路由列表
    @RequestMapping(value = "/list" , method = RequestMethod.GET)
    @ResponseBody
    public R<List<GatewayRouteDTO>> list(@RequestParam int page, @RequestParam int limit){
    	P<List<GatewayRouteDTO>> pageRt = gatewayRouteService.getPageList(page, limit);
        return R.success(pageRt);
    }

    @RequestMapping(value = "/delete" , method = RequestMethod.GET)
    @ResponseBody
    public  R<Boolean> delete(@RequestParam String ids){
    	if(StringUtils.isNotBlank(ids)) {
    		List<Long> idList = new ArrayList<>();
    		for(String id:ids.split(",")) {
    			if(StringUtils.isNotBlank(id)) {
    				idList.add(Long.valueOf(id));
    			}
    		}
    		int count = gatewayRouteService.delete(idList);
        	if(count > 0) {
        		return R.success();
        	}
    	}
    	
        return R.failure();
    }
    
    
    @GetMapping("/instances")
    @ResponseBody
    public R<List<Map<String, Object>>> instances(){
    	List<Map<String, Object>> rtMap = new ArrayList<>();
    	List<String> servers = getServiceInstance(AppInfo.APPLICATION_GATEWAY);
    	if(servers != null) {
    		for(String item:servers) {
    			String url = "http://"+ item;
    			Map<String, Object> obj = new HashMap<>();
    			obj.put("url", url);
    			rtMap.add(obj);
    		}
    	}
    	return R.success(rtMap);
    }
    
    private List<String> getServiceInstance(String appName){
		List<String> servers = new ArrayList<>();
		if(null != eurekaClient) {
			List<Application> apps = eurekaClient.getApplications().getRegisteredApplications();
			for(Application app : apps){
				if(app.getName().toLowerCase().equals(appName.toLowerCase())) {
					List<InstanceInfo> instances = app.getInstancesAsIsFromEureka();
					for(InstanceInfo instance : instances){
						servers.add(instance.getIPAddr()+":"+instance.getPort());
					}
				}
			}
		}
		return servers;
	}
}
